package com.fine.hair.manage.config;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.fine.hair.comm.dto.BasePage;
import com.fine.hair.comm.dto.rbac.AddAdminDto;
import com.fine.hair.comm.dto.rbac.ModifyAdminDto;
import com.fine.hair.comm.dto.rbac.ResetPasswordDto;
import com.fine.hair.comm.dto.rbac.ShutAdminDto;
import com.fine.hair.comm.enums.RoleType;
import com.fine.hair.comm.model.*;
import com.fine.hair.comm.utils.ApiResponse;
import com.fine.hair.comm.utils.MyStatus;
import com.fine.hair.comm.utils.PageInfo;
import com.fine.hair.comm.vo.AdminVo;
import com.fine.hair.manage.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author junelee
 * @date 2020/6/10 10:01
 */
@Slf4j
@Service
public class AuthService {

    @Autowired
    private SecUserMapper secUserMapper;

    @Autowired
    private SecPermissionMapper secPermissionMapper;

    @Autowired
    private SecUserRoleMapper secUserRoleMapper;

    @Autowired
    private SecRolePermissionMapper secRolePermissionMapper;

    @Autowired
    private Snowflake snowflake;

    @Autowired
    private BCryptPasswordEncoder encoder;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private BranchMapper branchMapper;

    @Transactional(rollbackFor = Exception.class)
    public ApiResponse addAdmin(AddAdminDto dto) {
        // 判断 phone 和 username 是否存在
        SecUser secUser = secUserMapper.selectByPhoneAndUsername(dto.getPhone(), dto.getUsername());
        if (secUser != null) {
            return ApiResponse.ofStatus(MyStatus.PHONE_OR_USERNAME_IS_EXIST);
        }
        SecUser secUser1 = new SecUser();
        secUser1.setId(snowflake.nextId());
        BeanUtils.copyProperties(dto, secUser1);
        secUser1.setPassword(bCryptPasswordEncoder.encode(dto.getPassword()));

        // 判断是不是站点管理员
        if (RoleType.BRANCH_ADMIN.getCode().equals(dto.getRole())) {
            secUser1.setBranchId(dto.getBranchId().stream().map(String::valueOf).collect(Collectors.joining(Constants.COMMA)));
        }

        SecUserRole secUserRole = new SecUserRole();
        secUserRole.setRoleId(dto.getRole());
        secUserRole.setUserId(secUser1.getId());
        secUserRoleMapper.insert(secUserRole);
        secUserMapper.insert(secUser1);

        return ApiResponse.ofSuccess();
    }


    private void createRolePermissionRelation(Long roleId, Long permissionId) {
        SecRolePermission adminPage = new SecRolePermission();
        adminPage.setRoleId(roleId);
        adminPage.setPermissionId(permissionId);
        secRolePermissionMapper.insert(adminPage);
    }

    private SecPermission createPermission(String icon, String url, String title, Integer type, String permission, String method, Integer sort, Long parentId) {
        SecPermission perm = new SecPermission();
        perm.setId(snowflake.nextId());
        perm.setIcon(icon);
        perm.setUrl(url);
        perm.setTitle(title);
        perm.setType(type);
        perm.setPermission(permission);
        perm.setMethod(method);
        perm.setSort(sort);
        perm.setParentId(parentId);
        secPermissionMapper.insert(perm);
        return perm;
    }

    private void createUserRoleRelation(Long userId, Long roleId) {
        SecUserRole userRole = new SecUserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(roleId);
        secUserRoleMapper.insert(userRole);
    }

    @Transactional(rollbackFor = Exception.class)
    public ApiResponse modifyAdmin(ModifyAdminDto dto) {
        // 查找出当前管理员的信息
        LambdaQueryWrapper<SecUserRole> qw = new LambdaQueryWrapper<>();
        qw.eq(SecUserRole::getUserId, dto.getSecUserId());
        SecUserRole one = secUserRoleMapper.selectOne(qw);
        // 检查是否存在该角色
        RoleType roleType = RoleType.fromCode(dto.getRole());
        if (roleType == null) {
            return ApiResponse.ofStatus(MyStatus.FAILED, "不存在此角色！");
        }
        // 修改角色
        LambdaQueryWrapper<SecUserRole> qw2 = new LambdaQueryWrapper<>();
        qw2.eq(SecUserRole::getUserId, dto.getSecUserId());
        one.setRoleId(roleType.getCode());

        SecUser secUser = secUserMapper.selectById(dto.getSecUserId());
        if (dto.getRole().equals(RoleType.BRANCH_ADMIN.getCode())) {
            secUser.setBranchId(dto.getBranchId().stream().map(String::valueOf).collect(Collectors.joining(Constants.COMMA)));
        } else if (dto.getRole().equals(RoleType.FINANCE_ADMIN.getCode())) {
            secUser.setBranchId(" ");
        }
        secUserMapper.updateById(secUser);
        secUserRoleMapper.update(one, qw2);
        return ApiResponse.ofSuccess();
    }

    public ApiResponse resetPassword(ResetPasswordDto dto) {
        // 获取管理员信息
        SecUser user = secUserMapper.selectById(dto.getUserId());
        if (user == null) {
            return ApiResponse.ofStatus(MyStatus.FAILED, "不存在此用户！");
        }
        user.setPassword(encoder.encode("123456"));
        LambdaQueryWrapper<SecUser> qw = new LambdaQueryWrapper<>();
        qw.eq(SecUser::getId, dto.getUserId());
        return secUserMapper.update(user, qw) > 0 ? ApiResponse.ofSuccess() : ApiResponse.ofStatus(MyStatus.FAILED);
    }

    public ApiResponse shutAdmin(ShutAdminDto dto) {
        // 获取管理员信息
        SecUser user = secUserMapper.selectById(dto.getUserId());
        if (user == null) {
            return ApiResponse.ofStatus(MyStatus.FAILED, "不存在此用户！");
        }
        return secUserMapper.deleteById(user.getId()) > 0 ? ApiResponse.ofSuccess() : ApiResponse.ofStatus(MyStatus.FAILED);
    }

    public PageInfo<AdminVo> adminList(BasePage basePage) {
        PageInfo<AdminVo> pageInfo = new PageInfo<>(basePage.getPageCurr(), basePage.getPageSize());
        // 获取所有管理员
        List<AdminVo> adminVoList = secUserMapper.selectSecUserList(pageInfo);
        pageInfo.setRecords(adminVoList);
        return pageInfo;
    }


    public ApiResponse<SecUser> clickEditGetInfo(Long secUserId) {
        SecUser secUser = secUserMapper.selectSecUserById(secUserId);
        if (StrUtil.isNotBlank(secUser.getBranchId())) {
            List<String> branchIds = Arrays.asList(secUser.getBranchId().split(Constants.COMMA));
            String branchTitles =
                    branchMapper.selectList(new LambdaQueryWrapper<Branch>().in(Branch::getId, branchIds)).stream().map(Branch::getTitle).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.joining(Constants.COMMA));
            secUser.setBranchTitles(branchTitles);
        }
        return ApiResponse.ofSuccess(secUser);
    }
}
